#pragma once

#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
#include <dxerr.h>
#pragma comment(lib, "dxerr.lib")
#include <sstream>

#include "Globals.h"
#include "Object Files.h"
#include "Light.h"
#include "Camera.h"

//Handles all directx drawing, camera information, and light information
//Dealls with the object3D list and the objectsprite list
class Pen
{
private:
	//DirectX Base
	Pen();
	IDirect3DDevice9*		m_pD3DDevice;
	HWND					m_hWnd;
	RECT					m_rClientRect;
	D3DPRESENT_PARAMETERS	m_D3DParams;

	//Light
	///////////////////////////////////////////////////
	LightObject				m_clCharacterLight;
	///////////////////////////////////////////////////

	//DirectX Camera
	///////////////////////////////////////////////////
	D3DXMATRIX				m_matView;
	D3DXMATRIX				m_matPerspective;
	///////////////////////////////////////////////////

	//DirectX Objects
	///////////////////////////////////////////////////
	ID3DXMesh*				m_pMeshBuffer[g_numMeshes];
	char*					m_cszMeshNameBuffer[g_numMeshes];
	TexturePack				m_stpTextureBuffer[g_numTextures];
	char*					m_cszTextureNameBuffer[g_numTextures];
	//DirectX Materials
	D3DMATERIAL9			m_DefaultMaterial;
	//DirectX Object Placement
	D3DXMATRIX				m_matTranslate;
	D3DXMATRIX				m_matRotate;
	D3DXMATRIX				m_matScale;
	D3DXMATRIX				m_matWorld;
	///////////////////////////////////////////////////

	//DirectX Sprites
	///////////////////////////////////////////////////
	ID3DXSprite*			m_pSpriteDevice;
	///////////////////////////////////////////////////

	//DirectX Font
	///////////////////////////////////////////////////
	ID3DXFont*				m_pD3DFont;
	RECT					m_FontScreenPosition[SCREENPOSITIONS];
	std::ostringstream		m_TextBuffer;
#ifdef _DEBUGGING
	std::ostringstream		m_DebugTextBuffer;
#endif
	bool					m_bRenderCredits;
	///////////////////////////////////////////////////

	//DirectX Specific Functions
	///////////////////////////////////////////////////
	bool InitDevice();
	bool InitFont();
	bool InitMeshes();
	bool InitTextures();
	///////////////////////////////////////////////////
public:
	~Pen();
	inline static Pen* Engine()
	{static Pen P;return &P;}

	bool Initialize(HWND hWnd);
	void LoadMeshFile(const char* cszXFile, ID3DXMesh*& pMesh);
	ID3DXMesh* getMeshByIndex(unsigned index);
	LPDIRECT3DTEXTURE9 getTextureByIndex(unsigned index);

	//Is handed all of the lists, then deals with them itself
	bool Draw(DrawList* drawlist3D,DrawList* drawlistSprite);

	//Handles all the types of rendering
	bool Render3D(DrawList* drawlist);
	bool RenderSprites(DrawList* drawlist);
	void RenderFont(string DisplayData);
	void RenderMenuFont(RECT Pos,LPCSTR Str);
	void RenderCredits();
	void StartCredits();
	void EndCredits();
#ifdef _DEBUGGING
	//Only used to display debug text
	void RenderDebugFont();	
	void DebugFont(string DisplayData){m_DebugTextBuffer << DisplayData;}
#endif
	void CheckDevice();
	const inline RECT GetClientRect() const {return m_rClientRect;}
};